package service

import (
	"fmt"
	"unicode/utf8"

	"go-file-perception-model/internal/logger"
)

// TextEncoder 文本编码处理器
type TextEncoder struct{}

// NewTextEncoder 创建文本编码处理器
func NewTextEncoder() *TextEncoder {
	return &TextEncoder{}
}

// EnsureUTF8 确保文本是有效的UTF-8编码
func (e *TextEncoder) EnsureUTF8(content []byte) string {
	// 如果已经是有效的UTF-8编码，直接返回
	if utf8.Valid(content) {
		return string(content)
	}

	// 如果不是有效的UTF-8编码，尝试修复
	logger.Warn("Content is not valid UTF-8, attempting to fix")
	
	// 尝试不同的编码转换
	// 方法1: 尝试GBK/GB2312转UTF-8
	text, err := e.decodeGBKToUTF8(content)
	if err == nil && utf8.Valid([]byte(text)) {
		return text
	}
	
	// 方法2: 尝试UTF-16转UTF-8
	text, err = e.decodeUTF16ToUTF8(content)
	if err == nil && utf8.Valid([]byte(text)) {
		return text
	}
	
	// 方法3: 使用简单的方法：替换无效的UTF-8序列为Unicode替换字符
	logger.Warn("Failed to convert from known encodings, using replacement method")
	var result []rune
	for i := 0; i < len(content); {
		r, size := utf8.DecodeRune(content[i:])
		if r == utf8.RuneError && size == 1 {
			// 无效的UTF-8序列，添加替换字符
			result = append(result, utf8.RuneError)
			i++
		} else {
			result = append(result, r)
			i += size
		}
	}
	return string(result)
}

// decodeGBKToUTF8 尝试将GBK/GB2312编码转换为UTF-8
func (e *TextEncoder) decodeGBKToUTF8(content []byte) (string, error) {
	var result []rune
	for i := 0; i < len(content); {
		b := content[i]
		if b < 128 {
			// ASCII字符，直接添加
			result = append(result, rune(b))
			i++
		} else if i+1 < len(content) {
			// 尝试处理双字节字符
			b1 := content[i]
			b2 := content[i+1]
			// 简单的GBK/GB2312字符范围检查
			if (b1 >= 0x81 && b1 <= 0xFE && b2 >= 0x40 && b2 <= 0xFE) ||
			   (b1 >= 0x81 && b1 <= 0xFE && b2 >= 0x30 && b2 <= 0x39) {
				// 可能是GBK/GB2312字符，使用替换字符代替
				result = append(result, '�')
				i += 2
			} else {
				// 未知字符，使用替换字符
				result = append(result, utf8.RuneError)
				i++
			}
		} else {
			// 单独的非ASCII字节，使用替换字符
			result = append(result, utf8.RuneError)
			i++
		}
	}
	return string(result), nil
}

// decodeUTF16ToUTF8 尝试将UTF-16编码转换为UTF-8
func (e *TextEncoder) decodeUTF16ToUTF8(content []byte) (string, error) {
	// 简单的UTF-16处理
	if len(content)%2 != 0 {
		return "", fmt.Errorf("invalid UTF-16 content length")
	}
	
	var result []rune
	for i := 0; i < len(content); i += 2 {
		b1 := content[i]
		b2 := content[i+1]
		codePoint := uint16(b1)<<8 | uint16(b2)
		
		// 处理BOM
		if i == 0 && (codePoint == 0xFEFF || codePoint == 0xFFFE) {
			continue // 跳过BOM
		}
		
		// 处理代理对
		if codePoint >= 0xD800 && codePoint <= 0xDBFF && i+2 < len(content) {
			b3 := content[i+2]
			b4 := content[i+3]
			lowSurrogate := uint16(b3)<<8 | uint16(b4)
			if lowSurrogate >= 0xDC00 && lowSurrogate <= 0xDFFF {
				// 有效的代理对
				highSurrogate := codePoint
				// 使用int32类型来处理超过uint16范围的码点
				fullCodePoint := int32((highSurrogate - 0xD800) << 10)
				fullCodePoint += int32(lowSurrogate - 0xDC00)
				fullCodePoint += 0x10000
				result = append(result, rune(fullCodePoint))
				i += 2
				continue
			}
		}
		
		result = append(result, rune(codePoint))
	}
	return string(result), nil
}

// EnsureUTF8Boundary 确保文本在UTF-8字符边界上开始和结束
func (e *TextEncoder) EnsureUTF8Boundary(text string) string {
	// 如果文本为空，直接返回
	if text == "" {
		return text
	}
	
	// 如果文本已经是有效的UTF-8编码，检查边界
	if utf8.ValidString(text) {
		// 检查第一个字符是否完整
		firstRune, firstSize := utf8.DecodeRuneInString(text)
		if firstRune == utf8.RuneError && firstSize == 1 {
			// 第一个字符不完整，需要截断
			for i := 1; i < len(text); i++ {
				if utf8.RuneStart(text[i]) {
					return text[i:]
				}
			}
			// 如果找不到UTF-8字符起始位置，返回空字符串
			return ""
		}
		
		// 检查最后一个字符是否完整
		lastRune, lastSize := utf8.DecodeLastRuneInString(text)
		if lastRune == utf8.RuneError && lastSize == 1 {
			// 最后一个字符不完整，需要截断
			for i := len(text) - 1; i >= 0; i-- {
				if utf8.RuneStart(text[i]) {
					return text[:i]
				}
			}
			// 如果找不到UTF-8字符起始位置，返回空字符串
			return ""
		}
		
		// 如果首尾字符都完整，直接返回
		return text
	}
	
	// 如果文本不是有效的UTF-8编码，尝试修复
	var result []rune
	for i := 0; i < len(text); {
		r, size := utf8.DecodeRuneInString(text[i:])
		if r == utf8.RuneError && size == 1 {
			// 无效的UTF-8序列，跳过
			i++
		} else {
			result = append(result, r)
			i += size
		}
	}
	return string(result)
}

// FindNearestUTF8Boundary 找到最近的UTF-8字符边界
func (e *TextEncoder) FindNearestUTF8Boundary(content string, pos int) int {
	// 如果位置已经是边界，直接返回
	if pos <= 0 || pos >= len(content) {
		return pos
	}
	
	// 检查当前位置是否是UTF-8字符的起始位置
	if utf8.RuneStart(content[pos]) {
		return pos
	}
	
	// 向前查找最近的UTF-8字符起始位置
	for i := pos - 1; i >= 0; i-- {
		if utf8.RuneStart(content[i]) {
			// 检查从这个位置开始的字符是否完整
			r, size := utf8.DecodeRuneInString(content[i:])
			if r != utf8.RuneError || size == 1 {
				// 如果字符完整，或者虽然不完整但已经是单个字节（无法修复），返回这个位置
				return i
			}
		}
	}
	
	// 如果向前找不到有效的UTF-8字符起始位置，尝试向后查找
	for i := pos; i < len(content); i++ {
		if utf8.RuneStart(content[i]) {
			// 检查从这个位置开始的字符是否完整
			r, size := utf8.DecodeRuneInString(content[i:])
			if r != utf8.RuneError || size == 1 {
				// 如果字符完整，或者虽然不完整但已经是单个字节（无法修复），返回这个位置
				return i
			}
		}
	}
	
	// 如果都找不到，返回0
	return 0
}